package org.micode.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class StringExtUtils extends StringUtils {

    private static final Pattern pattern = Pattern.compile("\\{(.*?)\\}");

    private static final String CHS_REGEX = "[\u2E80-\u2EFF\u2F00-\u2FDF\u31C0-\u31EF\u3400-\u4DBF\u4E00-\u9FFF\uF900-\uFAFF\uD840\uDC00-\uD869\uDEDF\uD869\uDF00-\uD86D\uDF3F\uD86D\uDF40-\uD86E\uDC1F\uD86E\uDC20-\uD873\uDEAF\uD87E\uDC00-\uD87E\uDE1F]+";

    /**
     * 判断字符串中是否包含中文汉字
     *
     * @param content
     * @return true至少包含1个
     */
    public static boolean hasChinese(CharSequence content) {
        if (null == content) {
            return false;
        }
        Pattern pattern = Pattern.compile(CHS_REGEX);
        return pattern.matcher(content).find();
    }

    /**
     * 判断字符串是否为中文汉字
     *
     * @param content
     * @return true都是汉字
     */
    public static boolean isChinese(CharSequence content) {
        if (null == content) {
            return false;
        }
        Pattern pattern = Pattern.compile(CHS_REGEX);
        return pattern.matcher(content).matches();
    }

    /**
     * 格式化字符串 字符串中使用{key}表示占位符
     *
     * @param sourStr 需要匹配的字符串
     * @param param   参数集
     * @return
     */
    public static String format(String sourStr, Map<String, Object> param) {
        String targetStr = sourStr;
        if (param == null)
            return targetStr;
        try {
            Matcher matcher = pattern.matcher(targetStr);
            while (matcher.find()) {
                String key = matcher.group();
                String keyclone = key.substring(1, key.length() - 1).trim();
                Object value = param.get(keyclone);
                if (value != null)
                    targetStr = targetStr.replace(key, value.toString());
            }
        } catch (Exception e) {
            log.error("Call StringExtUtils.format() failed", e);
            return null;
        }
        return targetStr;
    }


    /**
     * 使用正则表达式提取大括号中的内容
     *
     * @param msg
     * @return
     */
    public static List<String> extractMessageByBraces(String msg) {
        List<String> list = new ArrayList<>();
        Matcher m = pattern.matcher(msg);
        while (m.find()) {
            list.add(m.group().substring(1, m.group().length() - 1));
        }
        return list;
    }

    public static String filterUnVisualChar(String value) {
        if (null == value) {
            return null;
        }

        // 过滤掉不可见字符
        StringBuilder builder = new StringBuilder("");
        char[] charList = value.toCharArray();
        for (char c : charList) {
            if (c >= 0x20 && c <= 0x7E) {
                builder.append(c);
            }
        }
        return builder.toString();
    }

    public static String toHex(final String value) {
        char[] chars = "0123456789ABCDEF".toCharArray();
        StringBuilder builder = new StringBuilder("");
        byte[] bs = value.getBytes();
        int bit;
        for (int i = 0; i < bs.length; i++) {
            bit = (bs[i] & 0x0f0) >> 4;
            builder.append(chars[bit]);
            bit = bs[i] & 0x0f;
            builder.append(chars[bit]);
            builder.append(' ');
        }
        return builder.toString();
    }

    public static String getIdsStr(final Iterable<?> ids) {
        if (ids == null) {
            return null;
        }

        return StringUtils.join(ids, ",");
    }

    public static String idsString(List<?> ids) {
        if (ids == null || ids.size() <= 0) {
            return null;
        }

        StringBuilder sb = new StringBuilder();
        for (Object id : ids) {
            if (null != id) {
                sb.append(",").append("'").append(id.toString()).append("'");
            }
        }

        if (sb.length() > 0) {
            sb.deleteCharAt(0);
        } else {
            return null;
        }

        String idStr = sb.toString().trim();
        if (idStr.isEmpty()) {
            return null;
        }
        return idStr;
    }

    public static String firstToLowerCase(String str) {
        char[] chars = str.toCharArray();
        if (chars.length > 0 && chars[0] >= 'A' && chars[0] <= 'Z') {
            chars[0] = (char) (chars[0] - 'A' + 'a');
        }
        return new String(chars);
    }

    public static <K, V> String mapToString(Map<K, V> data) {
        if (null == data || data.size() <= 0) {
            return "[]";
        }

        StringBuilder sb = new StringBuilder();
        for (K key : data.keySet()) {
            sb.append(", ").append(key).append(":").append(data.get(key));
        }
        String ret = sb.toString();
        if (StringUtils.isNotBlank(ret)) {
            return "[" + ret.substring(2) + "]";
        } else {
            return "[" + ret + "]";
        }
    }
    public static <T> String listToString(List<T> data) {
        return listToString(data, false);
    }

    public static <T> String listToString(List<T> data, boolean haveQuote) {
        if (null == data || data.size() <= 0) {
            return "[]";
        }

        StringBuilder sb = new StringBuilder();
        for (T obj : data) {
            if (haveQuote) {
                sb.append(", \"").append(obj).append("\"");
            } else {
                sb.append(", ").append(obj);
            }
        }
        String ret = sb.toString();
        if (StringUtils.isNotBlank(ret)) {
            return "[" + ret.substring(2) + "]";
        } else {
            return "[" + ret + "]";
        }
    }

    public static String jsonArrayIds(String jsonArrayStr) {
        String val = jsonArrayStr.trim();
        if (StringExtUtils.isAnyEmpty(val)) {
            return null;
        }

        if (val.charAt(val.length() - 1) == ']') {
            val = val.substring(0, val.length() - 1);
        }

        if (val.length() > 0 && val.charAt(0) == '[') {
            val = val.substring(1);
        }

        return val.trim();
    }

    public static <T> String arrayToString(T[] arr) {
        return arrayToString(arr, false);
    }

    public static <T> String arrayToString(T[] arr, boolean haveQuote) {
        if (null == arr || arr.length <= 0) {
            return "[]";
        }

        StringBuilder sb = new StringBuilder();
        for (T obj : arr) {
            if (haveQuote) {
                sb.append(", \"").append(obj).append("\"");
            } else {
                sb.append(", ").append(obj);
            }
        }
        String ret = sb.toString();
        if (StringUtils.isNotBlank(ret)) {
            return "[" + ret.substring(2) + "]";
        } else {
            return "[" + ret + "]";
        }
    }

    public static String ltrim(String val) {
        return StringUtils.stripStart(val, null);
    }

    public static String rtrim(String val) {
        return StringUtils.stripEnd(val, null);
    }

    public static void main(String[] args) {
        String str = String.format("%s %s '%%%s%%'", 5424, "ertre", 4532542);
        System.out.println(str);
    }

}
